package Stream;

import Lambda.MethodReferences.Employee;
import Lambda.MethodReferences.EmployeeData;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @projectName: Java8
 * @package: Stream
 * @className: StreamTest
 * @author: 冷环渊 doomwatcher
 * @description:
 * <h3>
 *  1.Stream 关注的是对数据的运算，与CPU打交道
 *  集合关注的事数据的存储，与内存打交道
 *
 * 2.
 * - Stream 自己不会存储元素
 * - Stream 不会改变源对象 相反，他们会返回一个持有结果的新Stream
 * - Stream 操作是延时执行的，这意味的他们会等到需要结果的时候才执行
 *
 * 3. Stream 执行操作
 *    Stream 的实例化
 *    一系列的中间操作（过滤 映射 。。。。）
 *    终止操作
 *
 * 4. 说明
 * 4.1 一个中间操作链，对数据源进行处理
 * 4.2 一旦执行终止操作，就执行中间操作链，并产生结果，之后，不会再被使用
 *
 * </h3>
 * @date: 2021/12/12 1:37
 * @version: 1.0
 */
public class StreamTest {

    //Stream 创建方式一：通过集合
    @Test
    public void test1() {
        List<Employee> employees = EmployeeData.getEmployees();
        /*
         * default Stream<E> stream() 返回一个程序流
         * 这里我们用的是 Collection接口中就实现的方法
         *  default Stream<E> stream() {
         *    return StreamSupport.stream(spliterator(), false);
         *}
         * */
        Stream<Employee> stream = employees.stream();

        // default Stream<E> parallelStream() 返回一个并行流
        Stream<Employee> parallelStream = employees.parallelStream();
    }

    /**
     * @author 冷环渊 Doomwatcher
     * @context: 创建 Stream 的方式二 数组
     * Java 8 中 Arrays 的静态方法 stream（） 可以获取数组流
     *    IntStream stream = Arrays.stream(arr); static <T> Stream<T> stream(T[] array)返回一个流
     * 重载形式：
     * 能够处理 对应基本类型的数组
     *  ① public Static intStream stream(int[] array)
     *  ② public Static LongStraem stream(long[] array)
     *  ③ public Static DoubleStraam stream(double[] array)
     * @date: 2021/12/12 12:38
     * @param
     * @return:
     */
    @Test
    public void Test2() {
        int[] arr = {1, 2, 3, 4, 5, 6};
        IntStream stream = Arrays.stream(arr);
        Employee e1 = new Employee(1001, "tom");
        Employee e2 = new Employee(1002, "Treey");
        Employee[] employees = {e1, e2};
        Stream<Employee> employeeStream = Arrays.stream(employees);
    }

    /**
     * @author 冷环渊 Doomwatcher
     * @context:
     *  创建 Stream三 ： Stream本身的 of（） 我们需要创建数据的时候
     * @date: 2021/12/12 12:45
     * @param
     * @return: void
     */
    @Test
    public void Test3() {
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    }

    /**
     * @author 冷环渊 Doomwatcher
     * @context:
     * 创建方式四 创建无限流
     * 我们需要批量的产生数据
     * @date: 2021/12/12 12:47
     * @param
     * @return: void
     */
    @Test
    public void Test4() {
        /* 迭代
         * public static<T> Stream<T> iterate(final T sead,final UnaryOperator)
         * 遍历前十个偶数
         * 这里 参数 UNaryOperator继承自 function 也就是说我们最终调用的方法 是重写的apply
         * @FunctionalInterface
         * public interface UnaryOperator<T> extends Function<T, T> {
         * static <T> UnaryOperator<T> identity() {
         *   return t -> t;
         * }
         * }
         * */
        Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
        /*生成
         *  public static<T> Stream<T> generate(Supplier<T> s)
         *
         * */
        Stream.generate(Math::random).forEach(System.out::println);
    }
}
